package com.happysunrise.nru.services.imp;

import com.happysunrise.nru.enumerations.ResultTypeEnum;
import com.happysunrise.nru.managers.ITeamManager;
import com.happysunrise.nru.managers.IUserManager;
import com.happysunrise.nru.models.*;
import com.happysunrise.nru.services.IUserService;
import com.happysunrise.nru.utils.EncryptUtil;
import com.happysunrise.nru.utils.TokenUtil;
import io.swagger.models.auth.In;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * Created by liukaixin on 16/9/4.
 */
@Service
public class UserService implements IUserService {

    private static final Logger LOGGER = LoggerFactory
            .getLogger(UserService.class);

    @Autowired
    private IUserManager userManager;
    @Autowired
    private ITeamManager teamManager;

    /**
     * 登录.
     *
     * @param user 只带用户名和密码的user
     * @return 带着用户的结果集
     */
    @Override
    public Result<User> login(User user) {
        Result<User> result = new Result<>();
        LOGGER.debug("登录用户[{}]:", user.toString());
        User userInDb = userManager.login(user.getUsername());
        if (userInDb == null) {
            result.setCode(ResultTypeEnum.NO_SUCH_USER.getValue());
            result.setMessage(ResultTypeEnum.NO_SUCH_USER.getDescription());
            return result;
        }
        if (!userInDb.getPassword().equals(user.getPassword())) {
            result.setCode(ResultTypeEnum.UN_CORRECT_PWD.getValue());
            result.setMessage(ResultTypeEnum.UN_CORRECT_PWD.getDescription());
            return result;
        }
        userInDb.setToken(TokenUtil.getToken(userInDb.getId()));
        userManager.addToken(userInDb.getId(), userInDb.getToken());
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("登录" + ResultTypeEnum.SUCCESS.getDescription());
        LOGGER.debug("传到前端的登录用户[{}]:", userInDb.toString());
        result.setBean(userInDb);
        return result;
    }

    /**
     * 注册并登录.
     *
     * @param user user
     * @return 第几位用户
     */
    @Override
    public Result<User> register(User user) {
        Result<User> result = new Result<>();
        LOGGER.debug("注册的用户:[{}]", user.toString());
        Integer code = userManager.register(user);
        result.setCode(code);
        if (code.equals(ResultTypeEnum.SUCCESS.getValue())) {
            result.setMessage(getUserNum());
            User user1 = userManager.login(user.getUsername());
            user1.setToken(TokenUtil.getToken(user1.getId()));
            userManager.addToken(user1.getId(), user1.getToken());
            LOGGER.debug("传到前端的已登录用户[{}]:", user.toString());
            result.setBean(user1);
        } else if (code.equals(ResultTypeEnum.DUPLICATE_USER_NAME.getValue())) {
            result.setMessage(ResultTypeEnum.DUPLICATE_USER_NAME.getDescription());
        } else {
            result.setMessage("注册异常");
        }
        return result;
    }

    /**
     * 获得用户数量.
     *
     * @return 用户数量的string
     */
    private String getUserNum() {
        Integer userNumber = userManager.getUserNum();
        if (!userNumber.equals(ResultTypeEnum.WRONG_USER_COUNT.getValue())) {
            return "恭喜您,成为第" + userNumber + "位用户!";
        } else {
            return "感谢您的注册!";
        }
    }

    /**
     * 更新用户.
     *
     * @param user 修改的用户信息
     * @return 新的用户
     */
    @Override
    public Result<String> update(User user) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("更改用户成功");
        try {
            userManager.update(user);
        } catch (RuntimeException e) {
            LOGGER.error("更新用户异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("更新用户失败");
        }
        return result;
    }

    /**
     * 添加我的竞赛
     *
     * @param competition 竞赛实体
     * @param userId      用户Id
     * @return 结果集
     */

    public Result<String> addMyCompetition(Competition competition,
                                           Integer userId) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("加入我的竞赛" + ResultTypeEnum.SUCCESS.getDescription());
        try {
            Integer code = userManager.addMyCompetition(competition, userId);
            if (code != 1) {
                result.setCode(Result.FAILED);
                result.setMessage("添加竞赛失败，请检查网络连接或联系客服");
                LOGGER.error("添加我的竞赛失败");
                return result;
            }
        } catch (DuplicateKeyException e) {
            LOGGER.error("我的竞赛名重复异常", e);
            result.setCode(ResultTypeEnum.DUPLICATE_COMPETITION_NAME.getValue());
            result.setMessage("我的竞赛里已有该竞赛");
            return result;
        } catch (RuntimeException e) {
            LOGGER.error("添加我的竞赛异常", e);
            result.setCode(Result.FAILED);
            result.setMessage("RuntimeException");
            return result;
        }
        return result;
    }

    /**
     * 添加我的团队
     *
     * @param team 我的团队
     * @return 结果集
     */
    public Result<String> addMyTeam(UserTeam team) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("加入我的团队" + ResultTypeEnum.SUCCESS.getDescription());
        try {
            Integer code = userManager.addMyTeam(team);
            if (code != 1) {
                result.setCode(Result.FAILED);
                result.setMessage("添加团队失败，请检查网络连接或联系客服");
                LOGGER.error("添加我的团队失败");
                return result;
            }
        } catch (RuntimeException e) {
            LOGGER.error("添加我的团队异常", e);
            result.setCode(Result.FAILED);
            result.setMessage("RuntimeException");
            return result;
        }
        return result;
    }


    /**
     * 获取我的团队
     *
     * @param page   页码
     * @param rows   条数
     * @param userId 用户Id
     * @return 带有团队列表的结果集
     */
    @Override
    public Result<List<UserTeam>> getTeamsByUserId(Integer page,
                                                   Integer rows,
                                                   Integer userId) {
        Result<List<UserTeam>> result = new Result<>();
        result.setCode(Result.SUCCESS);
        List<UserTeam> myTeams = userManager
                .getTeamsByUserId(page, rows, userId);
        result.setBean(myTeams);
        return result;
    }

    /**
     * 获取我的收藏.
     *
     * @param page   页码
     * @param rows   条数
     * @param userId 用户Id
     * @return 带有收藏列表的结果集
     */
    @Override
    public Result<List<Favorite>> getFavoritesByUserId(Integer page,
                                                       Integer rows,
                                                       Integer userId) {
        Result<List<Favorite>> result = new Result<>();
        result.setCode(Result.SUCCESS);
        List<Favorite> myFavorites = userManager
                .getFavoritesByUserId(page, rows, userId);
        result.setBean(myFavorites);
        return result;
    }

    /**
     * 根据团队id和用户获取团队成员详情.
     *
     * @param teamId 团队id
     * @param userId 用户id
     * @return 结果集
     */
    @Override
    public Result<User> getUserByTeamIdAndUserId(Integer teamId, Integer userId) {
        Result<User> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("获取用户详情成功");
        try {
            User user = userManager.getUserByTeamIdAndUserId(teamId, userId);
            result.setBean(user);
        } catch (RuntimeException e) {
            LOGGER.error("根据id获取用户异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("获取用户异常");
        }
        return result;
    }

    /**
     * 根据id获取用户信息.
     *
     * @param userId 用户id
     * @return 结果集
     */
    @Override
    public Result<User> getUserInfoById(Integer userId) {
        Result<User> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("根据id获取用户详情成功");
        try {
            User user = userManager.getUserInfoById(userId);
            result.setBean(user);
        } catch (RuntimeException e) {
            LOGGER.error("根据id获取用户详情异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("根据id获取用户异常");
        }
        return result;
    }

    /**
     * 添加我的收藏.
     *
     * @param favorite 我的收藏
     * @return
     */
    @Override
    public Result<String> favorite(Favorite favorite) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("加入我的收藏" + ResultTypeEnum.SUCCESS.getDescription());
        try {
            Integer code = userManager.favorite(favorite);
            if (code != 1) {
                result.setCode(ResultTypeEnum.FAILED.getValue());
                result.setMessage("添加收藏失败，请检查网络连接或联系客服");
                LOGGER.error("添加我的收藏失败");
                return result;
            }
        } catch (DuplicateKeyException e) {
            LOGGER.error("重复添加我的收藏异常", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("重复收藏");
            return result;
        } catch (RuntimeException e) {
            LOGGER.error("添加我的收藏异常", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("添加我的收藏异常");
            return result;
        }
        return result;
    }

    @Override
    public Result<Boolean> getFavoriteOrNot(Integer starId, Integer userId) {
        Result<Boolean> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("获取收藏状态成功");
        try {
            Favorite favorite = userManager.getFavoriteByStarIdAndUserId(starId, userId);
            if (favorite == null) {
                result.setBean(false);
            } else {
                result.setBean(true);
            }
        } catch (RuntimeException e) {
            LOGGER.error("getFavoriteOrNot异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("获取收藏状态异常");
        }
        return result;
    }

    @Override
    public Result<String> cancelFavorite(Integer starId, Integer userId) {
        Result<String> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("取消收藏成功");
        try {
            Integer code = userManager.deleteFavorite(starId, userId);
            if (code != 1) {
                result.setCode(ResultTypeEnum.FAILED.getValue());
                result.setMessage("取消收藏异常");
            }
        } catch (RuntimeException e) {
            LOGGER.error("取消收藏异常:", e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("取消收藏异常");
        }
        return result;
    }

    @Override
    public Result<Integer> addUserPush(UserPush userPush) {
        Result<Integer> result = new Result<>();
        result.setCode(ResultTypeEnum.SUCCESS.getValue());
        result.setMessage("添加clientId成功");
        try {
            userManager.addUserPush(userPush);
        } catch (DuplicateKeyException e) {
            LOGGER.debug("该用户的clientId已经存在, 用户id是:", userPush.getUserId(), e);
            userManager.updateUserPush(userPush);
        } catch (RuntimeException e) {
            LOGGER.error("插入/更新用户推送异常: userPush = %s", userPush.toString(), e);
            result.setCode(ResultTypeEnum.FAILED.getValue());
            result.setMessage("添加推送失败");
        }
        return result;
    }

}

